package com.pe.siass.utils;

/**
 *
 * @author XPMUser
 */
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.oro.text.perl.Perl5Util;

public class UFiltro implements Filter
{
  /**
   * Este objeto tiene dos usos principales, obtener parámetros iniciales y
   * acceder al ServletContext del contenedor.
   */
  private FilterConfig filterConfig = null;
  /**
   * Lista de expresiones regulares a filtrar.
   */
  private Set regExps = null;

  /**
   * Resumen.
   * Método estándar, ejecutado para cargar recursos.
   *
   * @param filterConfigIni : Configuración del filtro, tipo FilterConfig
   * @throws javax.servlet.ServletException Objeto que captura excepciones que ocurren en el servlet.
   */
  @Override
  public void init(FilterConfig filterConfigIni) throws ServletException {
    filterConfig = filterConfigIni;
    regExps = new HashSet();

    BufferedReader lector = null;
    try {
        String path = filterConfig.getServletContext().getRealPath("/recursos/InfotFiltros.txt");
        lector = new BufferedReader(new FileReader(path));
        while (lector.ready()) {
            String regExp = lector.readLine().trim();
            if (regExp.length() > 0 && regExp.indexOf("#") != 0) {
                    regExps.add(regExp);
            }
        }
    } catch (IOException ioe) {
        System.out.println(ioe.toString());
        System.out.println("Error en: "+this.getClass().getName()+" producido por: "+ioe.getMessage());
    } finally {
        if (lector != null) {
            try {
                lector.close();
            } catch (IOException e) {
                System.out.println("Error en: "+this.getClass().getName()+" producido por: "+e.getMessage());
            }
        }
    }
  }

  /**
   * Resumen.
   * Es el encargado de destruir el servlet
   */
   @Override
   public void destroy() {
    this.filterConfig = null;
  }
   /**
   * Resumen.
   * Filtra los datos de las peticiones.
   *
   * @param request  : Contiene los parámetros y requerimientos del lado del cliente, tipo ServletRequest
   * @param response : Define métodos para responder a las peticiones del cliente, tipo ServletResponse
   * @param chain    : Se usa para invocar a siguiente filtro en la cadena, tipo FilterChain
   * @throws java.io.IOException Objeto que captura excepciones de entrada y salida de datos.
   * @throws javax.servlet.ServletException Objeto que captura excepciones que ocurren en el servlet.
   */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hreq = (HttpServletRequest) request;
        HttpServletResponse hres = (HttpServletResponse) response;
        if (!(request instanceof HttpServletRequest && response instanceof HttpServletResponse)) {
            throw new ServletException("Filtro aplicable.");
        }
        for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
            String parameterName = (String) e.nextElement();
            if (esInvalido(request.getParameter(parameterName))) {
                hres.sendRedirect(hreq.getContextPath() + "/noAutoriza.jsp");
                return;
            }
        }
        chain.doFilter(request, response);
    }

   /**
   * Resumen.
   * Verifica si la cadena ingresada es inválida. Para ello consulta una lista
   * de expresiones regulares a filtrar.
   *
   * @param cadena : Cadena a validar, tipo String
   * @return Resultado de la validacion (true => Si es valido la cadena; false => Si no es valido la cadena).
   */
  private boolean esInvalido(String cadena) {
    Perl5Util perl5 = new Perl5Util();
    for (Iterator i = regExps.iterator(); i.hasNext(); ) {
      if (perl5.match((String)i.next(), cadena)) {
        return true;
      }
    }
    return false;
  }
}